---
title: Retrieve a set of providers
summary: Loads a set of providers filtered by a tax-ID list or a caller-supplied WHERE clause, both built without bind parameters.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-21
library: SAIF.Business.View.Provider
reference_type: embedded
operation_id: OP-13
trigger: GetProviderCollection / GetProvidersUsingWhere caller request
---

# Retrieve a set of providers

Loads a `clsProviderCollection` filtered either by an array of tax IDs or by a caller-supplied raw WHERE clause, both appended to the base provider SELECT by string concatenation rather than bind variables.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-13 |
| **Trigger** | `GetProviderCollection(dpi, taxIDs())` / `GetProvidersUsingWhere(dpi, whereClause)` |
| **Inputs** | `IDataPortalInfo`; tax-ID array (`String()`) or a raw WHERE clause (`String`) |
| **Outputs** | `clsProviderCollection` |
| **Primary components** | `clsProviderCollection.GetProviderCollection`, `clsProviderCollection.GetProvidersUsingWhere` |
| **Entry point** | `SAIF.Business.View.Provider/clsProviderCollection.vb:182, 190` |

## Steps

1. `Criteria.BuildSQLWhere()` either emits the caller-supplied WHERE clause verbatim ([SQL-PRV-02b](../sql/SQL-PRV-02b-provider-collection-by-where.md)) or builds `where prv.primary_tax_id in ('…','…')` by string concatenation ([SQL-PRV-02](../sql/SQL-PRV-02-provider-collection-by-taxid.md)); the result is appended to `clsProvider.Criteria.RETRIEVE_SELECT_SQL` against [PROVIDER](../database-tables.md#provider).
2. `BeforeRetrieve` adds **no** parameters for either path.
3. `AfterRetrieve` loads one `clsProvider` per row.
   - Neither path uses bind variables, so both are exposed to SQL injection if a caller passes untrusted input ([BR-PRV-003](../business-rules.md#br-prv-003-provider-set-retrieval-uses-unparameterized-sql)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Caller request]) --> S1{Tax-ID list or WHERE clause?}
	S1 -->|Tax-ID array| S2[BuildSQLWhere: concatenate<br>IN 'tax1','tax2',...]
	S1 -->|Raw WHERE clause| S3["BuildSQLWhere: emit clause<br>verbatim"]
	S2 --> S4["Append to<br>RETRIEVE_SELECT_SQL"]
	S3 --> S4
	S4 --> S5[RetrieveObject via IDataPortalInfo<br>no bind parameters added]
	S5 --> S6["AfterRetrieve: load one<br>clsProvider per row"]
	S6 --> EndOk(["clsProviderCollection<br>returned"])
```

## Failure and edge-case behavior

- No matching rows: an empty `clsProviderCollection` is returned.
- Both retrieval paths concatenate untrusted input directly into SQL text with no bind variables, which is a SQL-injection risk if a caller passes untrusted input ([BR-PRV-003](../business-rules.md#br-prv-003-provider-set-retrieval-uses-unparameterized-sql)).
- No caller of `GetProvidersUsingWhere` was found in this repository, so the trust boundary for the WHERE-clause parameter cannot be established here.**

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Business.View.Provider/clsProviderCollection.vb`
